package prac6;
import static org.junit.Assert.assertTrue;
import org.junit.Test;

/**
 * Tests our Set class.
 * 
 * @author		Brendon Taylor
 * @modified	Menghong Li & Ian Moriarty (August 2011) - Added test cases
 * @since		August, 2009
 */
public class TestSet {
	private static Subject fit1001 = new Subject("FIT1001", "Computer systems");
	private static Subject fit1002 = new Subject("FIT1002", "Computer programming");
	private static Subject fit1003 = new Subject("FIT1003", "IT in organizations");
	private static Subject fit1004 = new Subject("FIT1004", "Database");
	private static Subject fit1005 = new Subject("FIT1005", "Networks and data communications");
	private static Subject fit1006 = new Subject("FIT1006", "Business information analysis");
	private static Subject fit1008 = new Subject("FIT1008", "Computer science");
	private static Subject fit1010 = new Subject("FIT1010", "Introduction to software engineering");	

	/**
	 * Tests the {@link Set#intersection(Set)} method.
	 *
	 * @see Set#intersection(Set)
	 * @complexity  best and worse case: O(I)
	 *              where I is the complexity of {@link Student#intersection(Student)}
	 */	
	@Test
	public void testIntersection() {

		Student student1 = new Student("Brendon", "Taylor");
		Student student2 = new Student("Chris", "Mears");
		Student student3 = new Student("Robyn", "McNamara");
		Student student4 = new Student("Maria", "Garcia de la banda");
		Student student5 = new Student("Menghong", "Li");
		Student student6 = new Student("Sheldon", "Cooper");
		Student student7 = new Student("Vincent", "Ren");
		Student student8 = new Student("Anakin", "Yue");
		
		// Test case 1: intersection between two empty sets
		LinkedSet<Subject> emptySet = new LinkedSet<Subject>();
		LinkedSet<Subject> intersectionSet1 = student1.intersection(student2);
		assertTrue(intersectionSet1.equals(emptySet));
		
		//Test case 2: intersection between two different sets
		LinkedSet<Subject> set1 = new LinkedSet<Subject>();
		set1.add(fit1003);
		student1.enrollSubject(fit1001);
		student1.enrollSubject(fit1002);
		student1.enrollSubject(fit1003);
		
		student2.enrollSubject(fit1003);
		student2.enrollSubject(fit1004);
		LinkedSet<Subject> intersectionSet2 = student1.intersection(student2);
		assertTrue(intersectionSet2.equals(set1));
		
		//Test case 3: intersection between one set and it's subset
		LinkedSet<Subject> set2 = new LinkedSet<Subject>();
		set2.add(fit1002);
		set2.add(fit1003);
		student3.enrollSubject(fit1001);
		student3.enrollSubject(fit1002);
		student3.enrollSubject(fit1003);
		
		student4.enrollSubject(fit1002);
		student4.enrollSubject(fit1003);
		LinkedSet<Subject> intersectionSet3 = student3.intersection(student4);
		assertTrue(intersectionSet3.equals(set2));
		
		//Test case 4: intersection between two disjoint sets
		student5.enrollSubject(fit1001);
		student5.enrollSubject(fit1002);
		student5.enrollSubject(fit1003);
		
		student6.enrollSubject(fit1004);
		student6.enrollSubject(fit1005);
		LinkedSet<Subject> intersectionSet4 = student5.intersection(student6);
		assertTrue(intersectionSet4.equals(emptySet));
		
		//Test case 5: 
		LinkedSet<Subject> set5 = new LinkedSet<Subject>();
		student7.enrollSubject(fit1001);
		student7.enrollSubject(fit1008);
		student7.enrollSubject(fit1003);
		
		student8.enrollSubject(fit1010);
		student8.enrollSubject(fit1006);
		student8.enrollSubject(fit1003);
		
		set5.add(fit1003);
		
		LinkedSet<Subject> intersectionSet5 = student7.intersection(student8);
		assertTrue(intersectionSet5.equals(set5));
	}
	
	@Test
	public void testIsMember(){
		LinkedSet<Subject> ls = new LinkedSet<Subject>();
		ls.add(fit1001);
		assertTrue(ls.isMember(fit1001));
		
		LinkedSet<Subject> emptySet= new LinkedSet<Subject>();
		assertTrue(!emptySet.isMember(fit1001));
	}
	
	@Test
	public void testClear() {
		LinkedSet<Subject> set6 = new LinkedSet<Subject>();
		assertTrue(set6.isEmpty());
		set6.clear();
		assertTrue(set6.isEmpty());
		
		set6.add(fit1001);
		set6.add(fit1006);
		assertTrue(!set6.isEmpty());
		set6.clear();
		assertTrue(set6.isEmpty());
	}
	
	@Test
	public void testDeleteItem() {
		LinkedSet<Subject> set7 = new LinkedSet<Subject>();
		assertTrue(!set7.deleteItem(fit1003));
		
		set7.add(fit1001);
		set7.add(fit1008);
		assertTrue(set7.isMember(fit1001));
		set7.deleteItem(fit1001);
		assertTrue(!set7.isMember(fit1001));
	}
	
	@Test
	public void testCardinality() {
		LinkedSet<Subject> set8 = new LinkedSet<Subject>();
		assertTrue(0 == set8.cardinality());
		
		set8.add(fit1001);
		set8.add(fit1008);
		assertTrue(2 == set8.cardinality());
		
		set8.clear();
		assertTrue(0 == set8.cardinality());
	}
	
	@Test
	public void testAdd() {
		LinkedSet<Subject> set9 = new LinkedSet<Subject>();
		assertTrue(set9.isEmpty());
		
		set9.add(fit1010);
		assertTrue(set9.isMember(fit1010));
	}
	
	@Test
	// test for FasterLinkedSet
	public void testFasterLinkedSet() {
		FasterLinkedSet<Integer> fset1 = new FasterLinkedSet<Integer>();
		fset1.add(2);
		fset1.add(17);
		fset1.add(10);
		fset1.add(9);
		
		FasterLinkedSet<Integer> fset2 = new FasterLinkedSet<Integer>();
		fset2.add(3);
		fset2.add(15);
		fset2.add(10);
		fset2.add(11);
		fset2.add(17);
		fset2.add(8);
		
		FasterLinkedSet<Integer> fset3 = new FasterLinkedSet<Integer>();
		fset3.add(10);
		fset3.add(17);
		
		FasterLinkedSet<Integer> intersectionSet = fset1.intersection(fset2);
		assertTrue(intersectionSet.equals(fset3));
	}
}